package com.pxmeta.party.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.pxmeta.common.exception.ServiceException;
import com.pxmeta.party.entity.ActivityAdAstra;
import com.pxmeta.party.entity.ActivityAdAstraRecord;
import com.pxmeta.party.entity.ActivityAdAstraUserRecord;
import com.pxmeta.party.entity.LotteryLuckyUser;
import com.pxmeta.party.entity.dto.ActivityAdAstraDTO;
import com.pxmeta.party.mapper.ActivityAdAstraUserRecordMapper;
import com.pxmeta.party.service.IActivityAdAstraService;
import com.pxmeta.party.service.IActivityAdAstraUserRecordService;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ActivityAdAstraUserRecordServiceImpl extends ServiceImpl<ActivityAdAstraUserRecordMapper, ActivityAdAstraUserRecord> implements IActivityAdAstraUserRecordService {
    @Autowired
    private IActivityAdAstraService activityAdAstraService;

    @Autowired
    private IUserService userService;


    @Override
    public void saveRecord(Long userId, Long recordId,Long successId, List<ActivityAdAstraDTO> dtos) {
        ActivityAdAstra adAstra = activityAdAstraService.getById(successId);
        List<ActivityAdAstraUserRecord> list = getByRecordId(recordId, userId);
        LinkedList<ActivityAdAstraUserRecord> saveList = Lists.newLinkedList();
        LinkedList<ActivityAdAstraUserRecord> updateList = Lists.newLinkedList();
        if (list.isEmpty()){
            //第一次派遣，保存记录
            for (ActivityAdAstraDTO dto : dtos) {
                ActivityAdAstraUserRecord userRecord = new ActivityAdAstraUserRecord();
                userRecord.setRecordId(recordId);
                userRecord.setUserId(userId);
                userRecord.setStarId(dto.getId());
                Integer count = dto.getCount();
                if (count>50){
                    throw new ServiceException("最多只能派遣50个！");
                }
                userRecord.setCount(count);
                userRecord.setRewardPrice(count * 500);
                //是否中奖
                if (dto.getId().equals(successId)){
                    //该用户已中奖。
                    userRecord.setStatus(1);
                }else {
                    userRecord.setStatus(0);
                }
                int coins = count * adAstra.getMagnification() * 500;
                userRecord.setRewardPrice(coins);
                saveList.add(userRecord);
            }
        }else {
            for (ActivityAdAstraDTO dto : dtos) {
                //包含，更新
                Optional<ActivityAdAstraUserRecord> first = list.stream().filter(l -> l.getStarId().equals(dto.getId())).findFirst();
                Integer count = dto.getCount();
                if (first.isPresent()){
                    ActivityAdAstraUserRecord userRecord = first.get();
                    int totalCount = userRecord.getCount() + count;
                    if (totalCount>50){
                        throw new ServiceException("最多只能派遣50个！");
                    }
                    userRecord.setCount(totalCount);
                    int coins = count * adAstra.getMagnification() * 500;
                    userRecord.setRewardPrice(userRecord.getRewardPrice()+coins);
                    updateList.add(userRecord);
                }else {
                    ActivityAdAstraUserRecord userRecord = new ActivityAdAstraUserRecord();
                    userRecord.setUserId(userId);
                    userRecord.setStarId(dto.getId());
                    userRecord.setCount(count);
                    if (count>50){
                        throw new ServiceException("最多只能派遣50个！");
                    }
                    userRecord.setRecordId(recordId);
                    //是否中奖
                    if (dto.getId().equals(successId)){
                        userRecord.setStatus(1);
                    }else {
                        userRecord.setStatus(0);
                    }
                    int coins = count * adAstra.getMagnification() * 500;
                    userRecord.setRewardPrice(coins);
                    saveList.add(userRecord);
                }
            }
        }


        if (!saveList.isEmpty()){
            this.saveBatch(saveList);
        }
        if (!updateList.isEmpty()){
            this.updateBatchById(updateList);
        }

    }

    @Override
    public List<ActivityAdAstraUserRecord> getByRecordId(Long recordId, Long userId) {
        LambdaQueryWrapper<ActivityAdAstraUserRecord> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ActivityAdAstraUserRecord::getRecordId, recordId)
                .eq(ActivityAdAstraUserRecord::getUserId, userId);
        return this.list(wrapper);
    }

    @Override
    public List<ActivityAdAstraUserRecord> getByRecordId(Long recordId) {
        LambdaQueryWrapper<ActivityAdAstraUserRecord> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ActivityAdAstraUserRecord::getRecordId, recordId);

        return this.list(wrapper);
    }

    @Override
    public IPage<LotteryLuckyUser> getUserLotteryRecordPage(Integer page, Integer size, String keyword) {
        User user = null;
        if (StringUtils.isNotBlank(keyword)){
            user = userService.getByAccount(keyword);
            if (user == null){
                throw new ServiceException("用户不存在！");
            }
        }
        LambdaQueryWrapper<ActivityAdAstraUserRecord> wrapper = Wrappers.lambdaQuery();

        if (user!=null){
            wrapper.eq(ActivityAdAstraUserRecord::getUserId, user.getId());
        }

        Page<LotteryLuckyUser> finalResult = new Page<>();

        List<LotteryLuckyUser> finalList = Lists.newLinkedList();
        wrapper.orderByDesc(ActivityAdAstraUserRecord::getCreateTime);
        Page<ActivityAdAstraUserRecord> result = this.page(new Page<>(page, size), wrapper);
        List<ActivityAdAstraUserRecord> records = result.getRecords();
        for (ActivityAdAstraUserRecord record : records) {
            User currentUser = userService.getById(record.getUserId());
            LotteryLuckyUser lotteryLuckyUser = new LotteryLuckyUser();
            lotteryLuckyUser.setNickname(currentUser.getNickname());
            lotteryLuckyUser.setAccount(currentUser.getAccount());
            lotteryLuckyUser.setRecordId(record.getRecordId());
            Long starId = record.getStarId();
            ActivityAdAstra star = activityAdAstraService.getById(starId);
            lotteryLuckyUser.setStarName(star.getName());
            lotteryLuckyUser.setLotteryType("星际探险");
            lotteryLuckyUser.setCount(record.getCount());
            lotteryLuckyUser.setConsumePrice(record.getCount()*500d);
            lotteryLuckyUser.setCreateTime(record.getCreateTime());
            Integer status = record.getStatus();
            if (status !=1){
                lotteryLuckyUser.setPrice(0);
            }else {
                lotteryLuckyUser.setPrice(record.getRewardPrice());
            }
            finalList.add(lotteryLuckyUser);
        }

        finalResult.setRecords(finalList);
        finalResult.setTotal(result.getTotal());

        return finalResult;


    }

    @Override
    public List<ActivityAdAstraUserRecord> getByRecordIds(List<Long> recordIds, Long userId) {
        LambdaQueryWrapper<ActivityAdAstraUserRecord> wrapper = Wrappers.lambdaQuery();
        wrapper.in(ActivityAdAstraUserRecord::getRecordId, recordIds)
                .eq(ActivityAdAstraUserRecord::getUserId, userId);
        return this.list(wrapper);
    }
}
